﻿/*基于捂脸猫FaceCat框架 v1.0
上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;

namespace FaceCat
{
    /// <summary>
    /// Gdi+绘图类
    /// </summary>
    public class GdiPlusPaint : FCPaint
    {
        /// <summary>
        /// 创建绘图类
        /// </summary>
        public GdiPlusPaint()
        {
        }

        /// <summary>
        /// 位图
        /// </summary>
        public Bitmap m_bitmap;

        /// <summary>
        /// 画刷
        /// </summary>
        public SolidBrush m_brush;

        /// <summary>
        /// 画刷的颜色
        /// </summary>
        public long m_brushColor;

        /// <summary>
        /// 空的字符串格式
        /// </summary>
        public StringFormat m_emptyStringFormat;

        /// <summary>
        /// 直线结束样式
        /// </summary>
        public int m_endLineCap;

        /// <summary>
        /// 导出路径
        /// </summary>
        public String m_exportPath;

        /// <summary>
        /// 绘图画面
        /// </summary>
        public Graphics m_g;

        /// <summary>
        /// 控件的HDC
        /// </summary>
        public IntPtr m_hDC;

        /// <summary>
        /// 图像缓存
        /// </summary>
        public HashMap<String, Bitmap> m_images = new HashMap<String, Bitmap>();

        /// <summary>
        /// 图像矩阵
        /// </summary>
        public static float[][] m_matrixItems = { new float[] { 1, 0, 0, 0, 0 }, new float[] { 0, 1, 0, 0, 0 }, new float[] { 0, 0, 1, 0, 0 }, new float[] { 0, 0, 0, 1, 0 }, new float[] { 0, 0, 0, 0, 1 } };

        /// <summary>
        /// 我的颜色
        /// </summary>
        public MyColor m_myColor = new MyColor();

        /// <summary>
        /// 横向偏移
        /// </summary>
        public int m_offsetX;

        /// <summary>
        /// 纵向偏移
        /// </summary>
        public int m_offsetY;

        /// <summary>
        /// 透明度
        /// </summary>
        public float m_opacity = 1;

        /// <summary>
        /// 绘图路径
        /// </summary>
        public GraphicsPath m_path;

        /// <summary>
        /// 画笔
        /// </summary>
        public Pen m_pen;

        /// <summary>
        ///  画笔的颜色 
        /// </summary>
        public long m_penColor;

        /// <summary>
        /// 画笔的宽度 
        /// </summary>
        public float m_penWidth;

        /// <summary>
        ///  画笔的样式 
        /// </summary>
        public int m_penStyle;

        /// <summary>
        /// 刷新区域
        /// </summary>
        public FCRect m_pRect;

        /// <summary>
        /// 资源路径
        /// </summary>
        public String m_resourcePath;

        /// <summary>
        /// 旋转角度
        /// </summary>
        public int m_rotateAngle;

        /// <summary>
        /// 横向缩放因子
        /// </summary>
        public double m_scaleFactorX = 1;

        /// <summary>
        /// 纵向缩放因子
        /// </summary>
        public double m_scaleFactorY = 1;

        /// <summary>
        /// 直线开始样式
        /// </summary>
        public int m_startLineCap;

        /// <summary>
        /// 窗口大小
        /// </summary>
        public FCRect m_wRect;

        public bool m_noSmooth = false;

        public const int FW_BOLD = 700;
        public const int FW_REGULAR = 400;
        public int GB2312_CHARSET = 134;
        public int OUT_DEFAULT_PRECIS = 0;
        public int CLIP_DEFAULT_PRECIS = 0;
        public int DEFAULT_QUALITY = 0;
        public int DEFAULT_PITCH = 0;
        public int FF_SWISS = 0;
        public const int DT_SINGLELINE = 0x20;
        public const int DT_TOP = 0;
        public const int DT_LEFT = 0;
        public const int DT_CENTER = 1;
        public const int DT_RIGHT = 2;
        public const int DT_VCENTER = 4;
        public const int DT_BOTTOM = 8;
        public const int DT_NOPREFIX = 0x00000800;
        public const int DT_WORD_ELLIPSIS = 0x00040000;
        public const int HOLLOW_BRUSH = 5;
        public const int IMAGE_BITMAP = 0;
        public const int LR_LOADFROMFILE = 0x00000010;
        public const int TRANSPARENT = 1;

        /// <summary>
        /// 位图对象
        /// </summary>
        public struct BITMAP
        {
            public int bmType; // set to 0
            public int bmWidth; // width in pixels
            public int bmHeight; // height in pixels
            public int bmWidthBytes; // width of row in bytes
            public short bmPlanes; // number of color planes
            public short bmBitsPixel; // number of bits per pixel
            public IntPtr bmBits; // pointer to pixel bits
        }

        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(
        IntPtr hdcDest,
        int nXDest,
        int nYDest,
        int nWidth,
        int nHeight,
        IntPtr hdcSrc,
        int nXSrc,
        int nYSrc,
        System.Int32 dwRop
        );

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateBitmapIndirect(ref BITMAP bm);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateFont(int H, int W, int E, int O, int FW, int I, int u, int S, int C, int OP, int CP, int Q, int PAF, String F);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreatePen(int style, int width, int dwPenColorREF);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateRectRgnIndirect(ref FCRect rect);

        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateSolidBrush(int dwPenColorREF);

        [DllImport("gdi32.dll")]
        public static extern bool DeleteDC(IntPtr hdc);

        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern int DrawText(IntPtr hdc, String lpStr, int nCount, ref FCRect lpRect, int wFormat);

        [DllImport("gdi32.dll")]
        public static extern int Ellipse(IntPtr hdc, int left, int top, int right, int bottom);

        [DllImport("user32.dll")]
        public static extern int FillRect(IntPtr hdc, ref FCRect lpRect, IntPtr brush);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int GetTextExtentPoint32(IntPtr hdc, String text, int length, ref FCSize size);

        [DllImport("gdi32.dll")]
        public static extern IntPtr GetStockObject(int fnObject);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int LineTo(IntPtr hdc, int x, int y);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern IntPtr LoadImage(IntPtr hinst, String lpszName, int uType, int cxDesired, int cyDesired, int fuLoad);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int MoveToEx(IntPtr hdc, int x, int y, IntPtr lpPoint);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int Polygon(IntPtr hdc, FCPoint[] apt, int cpt);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int Polyline(IntPtr hdc, FCPoint[] apt, int cpt);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int Rectangle(IntPtr hdc, int left, int top, int right, int bottom);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern int RoundRect(IntPtr hdc, int left, int top, int right, int bottom, int width, int height);

        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);

        [DllImport("gdi32.dll")]
        public static extern int SetBkMode(IntPtr hdc, int nBkMode);

        [DllImport("gdi32.dll")]
        public static extern int SelectClipRgn(IntPtr hdc, IntPtr hrgn);

        [DllImport("gdi32.dll")]
        public static extern int SetTextColor(IntPtr hdc, int dwPenColorREF);

        [DllImport("gdi32.dll")]
        public static extern bool StretchBlt(
        IntPtr hdcDest,
        int nXDest,
        int nYDest,
        int nWidth,
        int nHeight,
        IntPtr hdcSrc,
        int nXSrc,
        int nYSrc,
        int nWSrc,
        int nHSrc,
        System.Int32 dwRop
        );

        /// <summary>
        /// 是否使用云
        /// </summary>
        public bool m_useCloud = false;

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void addArc(FCRect rect, float startAngle, float sweepAngle)
        {
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_path.AddArc(gdiPlusRect, startAngle, sweepAngle);
            }
        }

        /// <summary>
        /// 添加贝赛尔曲线
        /// </summary>
        /// <param name="points">点阵</param>
        public override void addBezier(FCPoint[] points)
        {
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            m_path.AddBezier(gdiPlusPoints[0], gdiPlusPoints[1], gdiPlusPoints[2], gdiPlusPoints[3]);
        }

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="points">点阵</param>
        public override void addCurve(FCPoint[] points)
        {
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            m_path.AddCurve(gdiPlusPoints);
        }

        /// <summary>
        /// 添加椭圆
        /// </summary>
        /// <param name="rect">矩形</param>
        public override void addEllipse(FCRect rect)
        {
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_path.AddEllipse(gdiPlusRect);
            }
        }

        /// <summary>
        /// 添加直线
        /// </summary>
        /// <param name="x1">第一个点的横坐标</param>
        /// <param name="y1">第一个点的纵坐标</param>
        /// <param name="x2">第二个点的横坐标</param>
        /// <param name="y2">第二个点的纵坐标</param>
        public override void addLine(int x1, int y1, int x2, int y2)
        {
            int lx1 = x1 + m_offsetX;
            int ly1 = y1 + m_offsetY;
            int lx2 = x2 + m_offsetX;
            int ly2 = y2 + m_offsetY;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                lx1 = (int)(m_scaleFactorX * lx1);
                ly1 = (int)(m_scaleFactorY * ly1);
                lx2 = (int)(m_scaleFactorX * lx2);
                ly2 = (int)(m_scaleFactorY * ly2);
            }
            m_path.AddLine(lx1, ly1, lx2, ly2);
        }

        /// <summary>
        /// 添加矩形
        /// </summary>
        /// <param name="rect">区域</param>
        public override void addRect(FCRect rect)
        {
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_path.AddRectangle(gdiPlusRect);
            }
        }

        /// <summary>
        /// 添加扇形
        /// </summary>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void addPie(FCRect rect, float startAngle, float sweepAngle)
        {
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_path.AddPie(gdiPlusRect, startAngle, sweepAngle);
            }
        }

        /// <summary>
        /// 添加文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="font">字体</param>
        /// <param name="rect">区域</param>
        public override void addText(String text, FCFont font, FCRect rect, int width)
        {
            if (m_emptyStringFormat == null)
            {
                m_emptyStringFormat = StringFormat.GenericTypographic;
                //m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                int strX = (int)(m_scaleFactorX * (rect.left + m_offsetX));
                int strY = (int)(m_scaleFactorY * (rect.top + m_offsetY));
                float fontSize = (float)(font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2);
                FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                Font gdiplusFont = getFont(scaleFont);
                if (width == -1)
                {
                    Point gdiPlusPoint = new Point(strX, strY);
                    m_path.AddString(text, gdiplusFont.FontFamily, (int)gdiplusFont.Style, gdiplusFont.Size, gdiPlusPoint, m_emptyStringFormat);
                }
                else
                {
                    Rectangle gdiRect = new Rectangle(strX, strY,
                        (int)((rect.right - rect.left) * m_scaleFactorX),
                        (int)((rect.bottom - rect.top) * m_scaleFactorY));
                    if (gdiRect.Width > 0 && gdiRect.Height > 0)
                    {
                        m_path.AddString(text, gdiplusFont.FontFamily, (int)gdiplusFont.Style, gdiplusFont.Size, gdiRect, m_emptyStringFormat);
                    }
                }
            }
            else
            {
                Font gdiplusFont = getFont(font);
                if (width == -1)
                {
                    Point gdiPlusPoint = new Point(rect.left + m_offsetX, rect.top + m_offsetY);
                    m_path.AddString(text, gdiplusFont.FontFamily, (int)gdiplusFont.Style, gdiplusFont.Size, gdiPlusPoint, m_emptyStringFormat);
                }
                else
                {
                    Rectangle gdiRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
                    if (gdiRect.Width > 0 && gdiRect.Height > 0)
                    {
                        m_path.AddString(text, gdiplusFont.FontFamily, (int)gdiplusFont.Style, gdiplusFont.Size, gdiRect, m_emptyStringFormat);
                    }
                }
            }
        }

        /// <summary>
        /// 缩放因子生效
        /// </summary>
        /// <param name="gdiplusRect">矩形</param>
        public void affectScaleFactor(ref Rectangle gdiplusRect)
        {
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                gdiplusRect.Location = new Point((int)(gdiplusRect.Left * m_scaleFactorX),
                    (int)(gdiplusRect.Top * m_scaleFactorY));
                gdiplusRect.Width = (int)(gdiplusRect.Width * m_scaleFactorX);
                gdiplusRect.Height = (int)(gdiplusRect.Height * m_scaleFactorY);
            }
        }

        /// <summary>
        /// 缩放因子生效
        /// </summary>
        /// <param name="gdiplusRect">矩形</param>
        public void affectScaleFactor(ref RectangleF gdiplusRect)
        {
            if (m_scaleFactorX != -1 || m_scaleFactorY != -1)
            {
                gdiplusRect.Location = new PointF((float)(gdiplusRect.Left * m_scaleFactorX),
                    (float)(gdiplusRect.Top * m_scaleFactorY));
                gdiplusRect.Width = (float)(gdiplusRect.Width * m_scaleFactorX);
                gdiplusRect.Height = (float)(gdiplusRect.Height * m_scaleFactorY);
            }
        }

        /// <summary>
        /// 开始导出
        /// </summary>
        /// <param name="exportPath">路径</param>
        /// <param name="rect">区域</param>
        public override void beginExport(String exportPath, FCRect rect)
        {
            m_exportPath = exportPath;
            int imageW = rect.right - rect.left;
            int imageH = rect.bottom - rect.top;
            if (imageW == 0) imageW = 1;
            if (imageH == 0) imageH = 1;
            if (m_g != null)
            {
                m_g.Dispose();
            }
            if (m_bitmap != null)
            {
                m_bitmap.Dispose();
            }
            m_bitmap = new Bitmap(imageW, imageH);
            m_g = Graphics.FromImage(m_bitmap);
            m_g.TextRenderingHint = TextRenderingHint.AntiAlias;
            m_opacity = 1;
            m_resourcePath = null;
        }

        private Color m_lastClearColor = Color.Empty;

        /// <summary>
        /// 开始绘图
        /// </summary>
        /// <param name="hdc">HDC</param>
        /// <param name="wRect">窗体区域</param>
        /// <param name="pRect">刷新区域</param>
        public override void beginPaint(IntPtr hdc, FCRect wRect, FCRect pRect)
        {
            if (m_brush != null)
            {
                m_brush.Dispose();
                m_brush = null;
            }
            if (m_pen != null)
            {
                m_pen.Dispose();
                m_pen = null;
            }
            if (m_emptyStringFormat != null)
            {
                m_emptyStringFormat.Dispose();
                m_emptyStringFormat = null;
            }
            if (m_path != null)
            {
                m_path.Dispose();
                m_path = null;
            }
            m_pRect = pRect;
            m_wRect = wRect;
            int width = m_wRect.right - m_wRect.left;
            int height = m_wRect.bottom - m_wRect.top;
            if (m_bitmap == null || width > (int)m_bitmap.Width || height > (int)m_bitmap.Height)
            {
                if (m_g != null)
                {
                    m_g.Dispose();
                }
                int oldWidth = 0, oldHeight = 0;
                if (m_bitmap != null)
                {
                    oldWidth = m_bitmap.Width;
                    oldHeight = m_bitmap.Height;
                    m_bitmap.Dispose();
                }
                m_bitmap = new Bitmap(Math.Max(width, oldWidth), Math.Max(height, oldHeight));
                m_g = Graphics.FromImage(m_bitmap);
                m_g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                if (m_inputG != null)
                {
                    m_inputG.Dispose();
                }
                if (m_hDC != IntPtr.Zero)
                {
                    DeleteObject(m_hDC);
                }
                if (m_inputControl != null)
                {
                    m_inputG = m_inputControl.CreateGraphics();
                    m_hDC = m_inputG.GetHdc();
                }
            }
            if (m_noSmooth)
            {
                m_g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
                m_g.SmoothingMode = SmoothingMode.None;
            }
            //m_hDC = hdc;
            m_opacity = 1;
            m_resourcePath = null;
        }

        public BufferedGraphics m_myBuffer = null;

        /// <summary>
        /// 输入的控件
        /// </summary>
        public Control m_inputControl;

        /// <summary>
        /// 输入的对象
        /// </summary>
        public Graphics m_inputG;

        public int m_oldWidth;

        public int m_oldHeight;

        /// <summary>
        /// 开始绘图
        /// </summary>
        /// <param name="hdc">HDC</param>
        /// <param name="wRect">窗体区域</param>
        /// <param name="pRect">刷新区域</param>
        public void beginPaint2(FCRect wRect, FCRect pRect)
        {
            if (m_brush != null)
            {
                m_brush.Dispose();
                m_brush = null;
            }
            if (m_pen != null)
            {
                m_pen.Dispose();
                m_pen = null;
            }
            if (m_emptyStringFormat != null)
            {
                m_emptyStringFormat.Dispose();
                m_emptyStringFormat = null;
            }
            if (m_path != null)
            {
                m_path.Dispose();
                m_path = null;
            }
            m_pRect = pRect;
            m_wRect = wRect;
            int width = m_wRect.right - m_wRect.left;
            int height = m_wRect.bottom - m_wRect.top;
            BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
            if (m_myBuffer == null || width > m_oldWidth || height > m_oldHeight)
            {
                if (m_inputG != null)
                {
                    m_inputG.Dispose();
                }
                m_inputG = m_inputControl.CreateGraphics();
                m_myBuffer = currentContext.Allocate(m_inputG, new Rectangle(0, 0, width, height));
                m_g = m_myBuffer.Graphics;
                m_oldWidth = width;
                m_oldHeight = height;
            }
            if (m_noSmooth)
            {
                m_g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
                m_g.SmoothingMode = SmoothingMode.None;
            }
            //m_hDC = hdc;
            m_opacity = 1;
            m_resourcePath = null;
        }

        /// <summary>
        /// 开始一段路径
        /// </summary>
        public override void beginPath()
        {
            m_path = new GraphicsPath();
        }

        /// <summary>
        /// 清除缓存
        /// </summary>
        public override void clearCaches()
        {
            if (m_brush != null)
            {
                m_brush.Dispose();
                m_brush = null;
            }
            foreach (Image image in m_images.Values)
            {
                image.Dispose();
            }
            m_images.Clear();
            if (m_pen != null)
            {
                m_pen.Dispose();
                m_pen = null;
            }
            if (m_emptyStringFormat != null)
            {
                m_emptyStringFormat.Dispose();
                m_emptyStringFormat = null;
            }
            if (m_path != null)
            {
                m_path.Dispose();
                m_path = null;
            }
            if (m_bitmap != null)
            {
                m_bitmap.Dispose();
                m_bitmap = null;
            }
        }

        /// <summary>
        /// 裁剪路径
        /// </summary>
        public override void clipPath()
        {
            m_g.SetClip(m_path);
        }

        /// <summary>
        /// 闭合路径
        /// </summary>
        public override void closeFigure()
        {
            m_path.CloseFigure();
        }

        /// <summary>
        /// 结束一段路径
        /// </summary>
        public override void closePath()
        {
            m_path.Dispose();
            m_path = null;
        }

        /// <summary>
        /// 创建位图
        /// </summary>
        /// <param name="bitmap_ptr">Bitmap图像</param>
        /// <param name="rect">区域</param>
        /// <returns>位图</returns>
        public IntPtr create_hbitmap_from_gdiplus_bitmap(Bitmap bitmap_ptr, Rectangle rect)
        {
            rect.Intersect(new Rectangle(0, 0, bitmap_ptr.Width, bitmap_ptr.Height));
            if (rect.Width > 0 && rect.Height > 0)
            {
                BITMAP bm;
                BitmapData bmpdata = bitmap_ptr.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                bm.bmType = 0;
                bm.bmWidth = bmpdata.Width;
                bm.bmHeight = bmpdata.Height;
                bm.bmWidthBytes = bmpdata.Stride;
                bm.bmPlanes = 1;
                bm.bmBitsPixel = 32;
                bm.bmBits = bmpdata.Scan0;
                IntPtr hBitmap = CreateBitmapIndirect(ref bm);
                bitmap_ptr.UnlockBits(bmpdata);
                return hBitmap;
            }
            else
            {
                return IntPtr.Zero;
            }
        }

        /// <summary>
        /// 销毁对象
        /// </summary>
        public override void delete()
        {
            if (m_g != null)
            {
                m_g.Dispose();
                m_g = null;
            }
            if (m_bitmap != null)
            {
                m_bitmap.Dispose();
                m_bitmap = null;
            }
            clearCaches();
        }

        /// <summary>
        /// 绘制弧线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void drawArc(long dwPenColor, float width, int style, FCRect rect, float startAngle, float sweepAngle)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.DrawArc(getPen(dwPenColor, width, style), gdiPlusRect, startAngle, sweepAngle);
            }
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 设置贝赛尔曲线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">坐标阵1</param>
        public override void drawBezier(long dwPenColor, float width, int style, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.DrawBezier(getPen(dwPenColor, width, style), gdiPlusPoints[0], gdiPlusPoints[1], gdiPlusPoints[2], gdiPlusPoints[3]);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制曲线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">坐标阵</param>
        public override void drawCurve(long dwPenColor, float width, int style, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.DrawCurve(getPen(dwPenColor, width, style), gdiPlusPoints);
            m_g.SmoothingMode = SmoothingMode.Default;
        }


        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        public override void drawEllipse(long dwPenColor, float width, int style, FCRect rect)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.DrawEllipse(getPen(dwPenColor, width, style), gdiPlusRect);
            }
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void drawEllipse(long dwPenColor, float width, int style, int left, int top, int right, int bottom)
        {
            FCRect rect = new FCRect(left, top, right, bottom);
            drawEllipse(dwPenColor, width, style, rect);
        }

        /// <summary>
        /// 绘制图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        /// <param name="rect">绘制区域</param>
        public void drawImage2(String imagePath, FCRect rect)
        {
            try
            {
                int dw = rect.right - rect.left, dh = rect.bottom - rect.top;
                String imageKey = m_resourcePath + imagePath + dw.ToString() + dh.ToString();
                int rw = rect.right - rect.left;
                if (rw < 1) rw = 1;
                int rh = rect.bottom - rect.top;
                if (rh < 1) rh = 1;
                Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
                Bitmap drawImage = (Bitmap)Bitmap.FromFile(imagePath);
                if (drawImage != null)
                {
                    affectScaleFactor(ref gdiPlusRect);
                    if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
                    {
                        m_g.DrawImage(drawImage, new Rectangle(gdiPlusRect.Left, gdiPlusRect.Top, drawImage.Width, drawImage.Height), 0, 0, drawImage.Width, drawImage.Height, GraphicsUnit.Pixel);
                    }
                    drawImage.Dispose();
                }
            }
            catch (Exception ex)
            {
            }
        }

        public static int m_angle = 0;

        /// <summary>
        /// 绘制图片
        /// </summary>
        /// <param name="imagePath">图片路径</param>
        /// <param name="rect">绘制区域</param>
        public override void drawImage(String imagePath, FCRect rect)
        {
            int dw = rect.right - rect.left, dh = rect.bottom - rect.top;
            String imageKey = m_resourcePath + imagePath + "," + dw.ToString() + "," + dh.ToString();
            int rw = rect.right - rect.left;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top;
            if (rh < 1) rh = 1;
            Bitmap drawImage = null;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            if (m_images.ContainsKey(imageKey))
            {
                drawImage = m_images[imageKey];
            }
            else if (m_images.ContainsKey(imagePath))
            {
                drawImage = m_images[imagePath];
            }
            else
            {
                String[] attributes = new String[] { "file", "corner", "source", "highcolor", "lowcolor" };
                String[] values = new String[5];
                values[0] = imagePath;
                if (imagePath.IndexOf("=") != -1)
                {
                    for (int i = 0; i < attributes.Length; i++)
                    {
                        String attribute = attributes[i];
                        int alength = attribute.Length + 2;
                        int pos = imagePath.IndexOf(attribute + "=\'");
                        if (pos >= 0)
                        {
                            int rpos = imagePath.IndexOf("\'", pos + alength);
                            values[i] = imagePath.Substring(pos + alength, rpos - pos - alength);
                        }
                    }
                }
                String file = values[0];
                if (file.Length > 0)
                {
                    //fName = file.Substring(file.LastIndexOf("\\") + 1);
                }
                if (!File.Exists(file))
                {
                    if (m_resourcePath != null && m_resourcePath.Length > 0)
                    {
                        if (m_resourcePath.EndsWith("\\"))
                        {
                            file = m_resourcePath + file;
                        }
                        else
                        {
                            file = m_resourcePath + "\\" + file;
                        }
                    }
                }
                if (File.Exists(file))
                {
                    Bitmap image = null;
                    if (values[2] != null)
                    {
                        int[] source = new int[4];
                        String[] strs = values[2].Split(',');
                        for (int i = 0; i < strs.Length; i++)
                        {
                            source[i] = FCTran.strToInt(strs[i]);
                        }
                        Rectangle gdiPlusSourceRect = new Rectangle(source[0], source[1], source[2] - source[0], source[3] - source[1]);
                        Bitmap sourceImage = null;
                        try
                        {
                            sourceImage = (Bitmap)Bitmap.FromFile(file);
                        }
                        catch (Exception ex)
                        {
                        }
                        if (sourceImage != null)
                        {
                            image = new Bitmap(gdiPlusSourceRect.Width, gdiPlusSourceRect.Height);
                            Graphics sg = Graphics.FromImage(image);
                            sg.InterpolationMode = InterpolationMode.High;
                            sg.DrawImage(sourceImage, new Rectangle(0, 0, gdiPlusSourceRect.Width, gdiPlusSourceRect.Height), gdiPlusSourceRect, GraphicsUnit.Pixel);
                            sg.Dispose();
                            sourceImage.Dispose();
                        }
                    }
                    else
                    {
                        try
                        {
                            image = (Bitmap)Bitmap.FromFile(file);
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                    if (image != null)
                    {
                        long highColor = FCColor.None, lowColor = FCColor.None;
                        if (values[3] != null && values[4] != null)
                        {
                            highColor = FCTran.strToColor(values[3]);
                            lowColor = FCTran.strToColor(values[4]);
                        }
                        ImageAttributes imageAttr = new ImageAttributes();
                        if (highColor != FCColor.None && lowColor != FCColor.None)
                        {
                            int A = 0, R = 0, G = 0, B = 0;
                            FCColor.toRgba(this, highColor, ref R, ref G, ref B, ref A);
                            Color gdiPlusHighColor = Color.FromArgb(A, R, G, B);
                            FCColor.toRgba(this, lowColor, ref R, ref G, ref B, ref A);
                            Color gdiPlusLowColor = Color.FromArgb(A, R, G, B);
                            imageAttr.SetColorKey(gdiPlusLowColor, gdiPlusHighColor);
                        }
                        int iw = image.Width, ih = image.Height;
                        dw = (int)(dw * m_scaleFactorX);
                        dh = (int)(dh * m_scaleFactorY);
                        if (dw > iw)
                        {
                            dw = iw;
                        }
                        if (dh > ih)
                        {
                            dh = ih;
                        }
                        drawImage = new Bitmap(dw, dh);
                        Graphics g = Graphics.FromImage(drawImage);
                        //g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.InterpolationMode = InterpolationMode.High;
                        if (values[1] == null)
                        {
                            g.DrawImage(image, new Rectangle(0, 0, dw, dh),
                                0, 0, iw, ih, GraphicsUnit.Pixel, imageAttr);
                        }
                        else
                        {
                            int[] corners = new int[4];
                            String[] strs = values[1].Split(',');
                            for (int i = 0; i < strs.Length; i++)
                            {
                                corners[i] = FCTran.strToInt(strs[i]);
                            }
                            int left = 0;
                            int top = 0;
                            int right = iw;
                            int bottom = ih;
                            if (corners[0] > 0)
                            {
                                g.DrawImage(image, new Rectangle(left, top, corners[0], ih),
                                    0, 0, corners[0], ih, GraphicsUnit.Pixel, imageAttr);
                            }
                            if (corners[1] > 0)
                            {
                                g.DrawImage(image, new Rectangle(left, top, iw, corners[1]),
                                0, 0, iw, corners[1], GraphicsUnit.Pixel, imageAttr);
                            }
                            if (corners[2] > 0)
                            {
                                g.DrawImage(image, new Rectangle(right - corners[2], top, corners[2], ih),
                                    iw - corners[2], 0, corners[2], ih, GraphicsUnit.Pixel, imageAttr);
                            }
                            if (corners[3] > 0)
                            {
                                g.DrawImage(image, new Rectangle(left, bottom - corners[3], iw, corners[3]),
                                    0, ih - corners[3], iw, corners[3], GraphicsUnit.Pixel, imageAttr);
                            }
                            int cwdest = iw - corners[0] - corners[2];
                            int chdest = ih - corners[1] - corners[3];
                            int cwsrc = iw - corners[0] - corners[2];
                            int chsrc = ih - corners[1] - corners[3];
                            if (cwdest > 0 && chdest > 0 && cwsrc > 0 && chsrc > 0)
                            {
                                g.DrawImage(image, new Rectangle(left + corners[0], top + corners[1], cwdest, chdest),
                                corners[0], corners[1], cwsrc, chsrc, GraphicsUnit.Pixel, imageAttr);
                            }
                        }
                        imageAttr.Dispose();
                        g.Dispose();
                        image.Dispose();
                        m_images[imageKey] = drawImage;
                    }
                }
            }
            if (drawImage != null)
            {
                affectScaleFactor(ref gdiPlusRect);
                if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
                {
                    //m_g.SmoothingMode = SmoothingMode.AntiAlias;
                    InterpolationMode oldMode = m_g.InterpolationMode;
                    //CompositingQuality oldQuality = m_g.CompositingQuality;
                    m_g.InterpolationMode = InterpolationMode.High;//高质量
                    //m_g.CompositingQuality = CompositingQuality.HighQuality;
                    if (m_opacity < 1)
                    {
                        m_matrixItems[3][3] = m_opacity;
                        ColorMatrix colorMatrix = new ColorMatrix(m_matrixItems);
                        ImageAttributes imageAttr = new ImageAttributes();
                        imageAttr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                        m_g.DrawImage(drawImage, gdiPlusRect, 0, 0, drawImage.Width, drawImage.Height, GraphicsUnit.Pixel, imageAttr);
                        imageAttr.Dispose();
                    }
                    else
                    {
                        m_g.DrawImage(drawImage, gdiPlusRect, 0, 0, drawImage.Width, drawImage.Height, GraphicsUnit.Pixel);
                    }
                    m_g.InterpolationMode = oldMode;
                }
                //m_g.InterpolationMode = oldMode;//高质量
                //m_g.CompositingQuality = oldQuality;
                //m_g.SmoothingMode = SmoothingMode.Default;
            }
        }

        /// <summary>
        /// 绘制直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="x1">第一个点的横坐标</param>
        /// <param name="y1">第一个点的纵坐标</param>
        /// <param name="x2">第二个点的横坐标</param>
        /// <param name="y2">第二个点的纵坐标</param>
        public override void drawLine(long dwPenColor, float width, int style, int x1, int y1, int x2, int y2)
        {
            if (dwPenColor == FCColor.None) return;
            int lx1 = x1 + m_offsetX;
            int ly1 = y1 + m_offsetY;
            int lx2 = x2 + m_offsetX;
            int ly2 = y2 + m_offsetY;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                lx1 = (int)(m_scaleFactorX * lx1);
                ly1 = (int)(m_scaleFactorY * ly1);
                lx2 = (int)(m_scaleFactorX * lx2);
                ly2 = (int)(m_scaleFactorY * ly2);
            }
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.DrawLine(getPen(dwPenColor, width, style), lx1, ly1, lx2, ly2);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="x1">第一个点的横坐标</param>
        /// <param name="y1">第一个点的纵坐标</param>
        /// <param name="x2">第二个点的横坐标</param>
        /// <param name="y2">第二个点的纵坐标</param>
        public void drawLine2(long dwPenColor, float width, int style, int x1, int y1, int x2, int y2)
        {
            if (dwPenColor == FCColor.None) return;
            int lx1 = x1 + m_offsetX;
            int ly1 = y1 + m_offsetY;
            int lx2 = x2 + m_offsetX;
            int ly2 = y2 + m_offsetY;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                lx1 = (int)(m_scaleFactorX * lx1);
                ly1 = (int)(m_scaleFactorY * ly1);
                lx2 = (int)(m_scaleFactorX * lx2);
                ly2 = (int)(m_scaleFactorY * ly2);
            }
            m_g.SmoothingMode = SmoothingMode.Default;
            m_g.DrawLine(getPen(dwPenColor, width, style), lx1, ly1, lx2, ly2);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="x">第一个点的坐标</param>
        /// <param name="y">第二个点的坐标</param>
        public override void drawLine(long dwPenColor, float width, int style, FCPoint x, FCPoint y)
        {
            drawLine(dwPenColor, width, style, x.x, x.y, y.x, y.y);
        }

        /// <summary>
        /// 绘制路径
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        public override void drawPath(long dwPenColor, float width, int style)
        {
            if (dwPenColor == FCColor.None) return;
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.DrawPath(getPen(dwPenColor, width, style), m_path);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制扇形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void drawPie(long dwPenColor, float width, int style, FCRect rect, float startAngle, float sweepAngle)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.DrawPie(getPen(dwPenColor, width, style), gdiPlusRect, startAngle, sweepAngle);
            }
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制多边形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">点的数组</param>
        public override void drawPolygon(long dwPenColor, float width, int style, FCPoint[] points)
        {
            if (points.Length == 1)
            {
                drawLine(dwPenColor, width, style, points[0].x, points[0].y, points[0].x, points[0].y);
                return;
            }
            if (dwPenColor == FCColor.None) return;
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.DrawPolygon(getPen(dwPenColor, width, style), gdiPlusPoints);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制大量直线
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="points">点集</param>
        public override void drawPolyline(long dwPenColor, float width, int style, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            Point[] gdiPlusPoints = new Point[points.Length];
            int lx = 0, ly = 0;
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
                if (m_useCloud)
                {
                    lx = x;
                    ly = y;
                }
            }
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.DrawLines(getPen(dwPenColor, width, style), gdiPlusPoints);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        public override void drawRect(long dwPenColor, float width, int style, FCRect rect)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.SmoothingMode = SmoothingMode.Default;
                m_g.DrawRectangle(getPen(dwPenColor, width, style), gdiPlusRect);
            }
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void drawRect(long dwPenColor, float width, int style, int left, int top, int right, int bottom)
        {
            FCRect rect = new FCRect(left, top, right, bottom);
            drawRect(dwPenColor, width, style, rect);
        }

        /// <summary>
        /// 绘制圆角矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="cornerRadius">边角半径</param>
        public override void drawRoundRect(long dwPenColor, float width, int style, FCRect rect, int cornerRadius)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (cornerRadius != 0)
            {
                GraphicsPath gdiPlusPath = getRoundRectPath(gdiPlusRect, (int)(cornerRadius * Math.Min(m_scaleFactorX, m_scaleFactorY)));
                if (!m_noSmooth)
                {
                    m_g.SmoothingMode = SmoothingMode.AntiAlias;
                }
                m_g.DrawPath(getPen(dwPenColor, width, style), gdiPlusPath);
                m_g.SmoothingMode = SmoothingMode.Default;
                gdiPlusPath.Dispose();
            }
            else
            {
                if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
                {
                    m_g.SmoothingMode = SmoothingMode.Default;
                    m_g.DrawRectangle(getPen(dwPenColor, width, style), gdiPlusRect);
                }
            }
        }

        /// <summary>
        /// 绘制圆角矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="cornerRadius">边角半径</param>
        public void drawRoundRect2(long dwPenColor, float width, int style, FCRect rect, int cornerRadius)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (cornerRadius != 0)
            {
                GraphicsPath gdiPlusPath = getRoundRectPath(gdiPlusRect, (int)(cornerRadius * Math.Min(m_scaleFactorX, m_scaleFactorY)));
                m_g.SmoothingMode = SmoothingMode.Default;
                m_g.DrawPath(getPen(dwPenColor, width, style), gdiPlusPath);
                m_g.SmoothingMode = SmoothingMode.Default;
                gdiPlusPath.Dispose();
            }
            else
            {
                m_g.SmoothingMode = SmoothingMode.Default;
                m_g.DrawRectangle(getPen(dwPenColor, width, style), gdiPlusRect);
            }
        }

        /// <summary>
        /// 绘制文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="font">字体</param>
        /// <param name="rect">矩形区域</param>
        public override void drawText(String text, long dwPenColor, FCFont font, FCRect rect, int width)
        {
            if (dwPenColor == FCColor.None) return;
            if (m_emptyStringFormat == null)
            {
                m_emptyStringFormat = StringFormat.GenericTypographic;
                //m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                int strX = (int)(m_scaleFactorX * (rect.left + m_offsetX));
                int strY = (int)(m_scaleFactorY * (rect.top + m_offsetY));
                float fontSize = (float)(font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2);
                FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                if (font.m_angle != 0)
                {
                    Rectangle gdiRect = new Rectangle(strX, strY,
                            (int)((rect.right - rect.left) * m_scaleFactorX),
                            (int)((rect.bottom - rect.top) * m_scaleFactorY));
                    GraphicsState state = m_g.Save();
                    m_g.TranslateTransform(gdiRect.Left + gdiRect.Width / 2, gdiRect.Top + gdiRect.Height / 2);
                    m_g.RotateTransform(font.m_angle);
                    Point gdiPlusPoint = new Point(-gdiRect.Width / 2, -gdiRect.Height / 2);
                    m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    m_g.Restore(state);
                }
                else
                {
                    if (width == -1)
                    {
                        Point gdiPlusPoint = new Point(strX, strY);
                        m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    }
                    else
                    {
                        Rectangle gdiRect = new Rectangle(strX, strY,
                            (int)((rect.right - rect.left) * m_scaleFactorX),
                            (int)((rect.bottom - rect.top) * m_scaleFactorY));
                        if (gdiRect.Width > 0 && gdiRect.Height > 0)
                        {
                            m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), gdiRect, m_emptyStringFormat);
                        }
                    }
                }
            }
            else
            {
                if (font.m_angle != 0)
                {
                    Rectangle gdiRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
                    GraphicsState state = m_g.Save();
                    m_g.TranslateTransform(gdiRect.Left + gdiRect.Width / 2, gdiRect.Top + gdiRect.Height / 2);
                    m_g.RotateTransform(font.m_angle);
                    Point gdiPlusPoint = new Point(-gdiRect.Width / 2, -gdiRect.Height / 2);
                    m_g.DrawString(text, getFont(font), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    m_g.Restore(state);
                }
                else
                {
                    if (width == -1)
                    {
                        Point gdiPlusPoint = new Point(rect.left + m_offsetX, rect.top + m_offsetY);
                        m_g.DrawString(text, getFont(font), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    }
                    else
                    {
                        Rectangle gdiRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
                        m_g.DrawString(text, getFont(font), getBrush(dwPenColor), gdiRect, m_emptyStringFormat);
                    }
                }
            }
        }

        /// <summary>
        /// 绘制文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="font">字体</param>
        /// <param name="rect">矩形区域</param>
        public override void drawText(String text, long dwPenColor, FCFont font, FCRectF rect, int width)
        {
            if (dwPenColor == FCColor.None) return;
            if (m_emptyStringFormat == null)
            {
                m_emptyStringFormat = StringFormat.GenericTypographic;
                //m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                float strX = (float)(m_scaleFactorX * (rect.left + m_offsetX));
                float strY = (float)(m_scaleFactorY * (rect.top + m_offsetY));
                float fontSize = (float)(font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2);
                FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                if (font.m_angle != 0)
                {
                    RectangleF gdiRect = new RectangleF(strX, strY,
                            (float)((rect.right - rect.left) * m_scaleFactorX),
                            (float)((rect.bottom - rect.top) * m_scaleFactorY));
                    GraphicsState state = m_g.Save();
                    m_g.TranslateTransform(gdiRect.Left + gdiRect.Width / 2, gdiRect.Top + gdiRect.Height / 2);
                    m_g.RotateTransform(font.m_angle);
                    PointF gdiPlusPoint = new PointF(-gdiRect.Width / 2, -gdiRect.Height / 2);
                    m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    m_g.Restore(state);
                }
                else
                {
                    if (width == -1)
                    {
                        PointF gdiPlusPoint = new PointF(strX, strY);
                        m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    }
                    else
                    {
                        RectangleF gdiRect = new RectangleF(strX, strY,
                            (float)((rect.right - rect.left) * m_scaleFactorX),
                            (float)((rect.bottom - rect.top) * m_scaleFactorY));
                        if (gdiRect.Width > 0 && gdiRect.Height > 0)
                        {
                            m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), new PointF(gdiRect.Left, gdiRect.Top), m_emptyStringFormat);
                        }
                    }
                }
            }
            else
            {
                if (font.m_angle != 0)
                {
                    RectangleF gdiRect = new RectangleF(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
                    GraphicsState state = m_g.Save();
                    m_g.TranslateTransform(gdiRect.Left + gdiRect.Width / 2, gdiRect.Top + gdiRect.Height / 2);
                    m_g.RotateTransform(font.m_angle);
                    PointF gdiPlusPoint = new PointF(-gdiRect.Width / 2, -gdiRect.Height / 2);
                    m_g.DrawString(text, getFont(font), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    m_g.Restore(state);
                }
                else
                {
                    if (width == -1)
                    {
                        PointF gdiPlusPoint = new PointF(rect.left + m_offsetX, rect.top + m_offsetY);
                        m_g.DrawString(text, getFont(font), getBrush(dwPenColor), gdiPlusPoint, m_emptyStringFormat);
                    }
                    else
                    {
                        RectangleF gdiRect = new RectangleF(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
                        m_g.DrawString(text, getFont(font), getBrush(dwPenColor), new PointF(gdiRect.Left, gdiRect.Top), m_emptyStringFormat);
                    }
                }
            }
        }

        /// <summary>
        /// 绘制自动省略结尾的文字
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="font">字体</param>
        /// <param name="rect">矩形区域</param>
        public override void drawTextAutoEllipsis(String text, long dwPenColor, FCFont font, FCRect rect)
        {
            if (dwPenColor == FCColor.None) return;
            if (m_emptyStringFormat == null)
            {
                m_emptyStringFormat = StringFormat.GenericTypographic;
                //m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            m_emptyStringFormat.Trimming = StringTrimming.EllipsisCharacter;
            m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                affectScaleFactor(ref gdiPlusRect);
                if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
                {
                    float fontSize = (float)(font.m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2);
                    FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                    m_g.DrawString(text, getFont(scaleFont), getBrush(dwPenColor), gdiPlusRect, m_emptyStringFormat);
                }
            }
            else
            {
                m_g.DrawString(text, getFont(font), getBrush(dwPenColor), gdiPlusRect, m_emptyStringFormat);
            }
            m_emptyStringFormat.Trimming = StringTrimming.None;
            m_emptyStringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
        }

        /// <summary>
        /// 结束导出
        /// </summary>
        public override void endExport()
        {
            if (m_bitmap != null)
            {
                m_bitmap.Save(m_exportPath, ImageFormat.Png);
            }
            if (m_g != null)
            {
                m_g.Dispose();
                m_g = null;
            }
            if (m_bitmap != null)
            {
                m_bitmap.Dispose();
                m_bitmap = null;
            }
            m_offsetX = 0;
            m_offsetY = 0;
            m_opacity = 1;
            m_resourcePath = null;
        }

        /// <summary>
        /// 结束绘图
        /// </summary>
        public void endPaint2()
        {
            if (m_myBuffer != null)
            {
                m_myBuffer.Render();
                //m_myBuffer.Dispose();
            }
            //m_g.Dispose();
            m_offsetX = 0;
            m_offsetY = 0;
            m_opacity = 1;
            m_resourcePath = "";
        }

        /// <summary>
        /// 结束绘图
        /// </summary>
        public override void endPaint()
        {
            Rectangle clipRect = new Rectangle(m_pRect.left, m_pRect.top, m_pRect.right - m_pRect.left, m_pRect.bottom - m_pRect.top);
            affectScaleFactor(ref clipRect);
            int width = m_wRect.right - m_wRect.left;
            int height = m_wRect.bottom - m_wRect.top;
            if (clipRect.Width < width || clipRect.Height < height)
            {
                if (clipRect.X < m_wRect.left)
                {
                    clipRect.Width += clipRect.X;
                    clipRect.X = m_wRect.left;
                }
                if (clipRect.Y < m_wRect.top)
                {
                    clipRect.Height += clipRect.Y;
                    clipRect.Y = m_wRect.top;
                }
                if (clipRect.Right > m_wRect.right)
                {
                    clipRect.Width -= Math.Abs(clipRect.Right - m_wRect.right);
                }
                if (clipRect.Bottom > m_wRect.bottom)
                {
                    clipRect.Height -= Math.Abs(clipRect.Bottom - m_wRect.bottom);
                }
                if (clipRect.Width > 0 && clipRect.Height > 0)
                {
                    IntPtr bitmap = create_hbitmap_from_gdiplus_bitmap(m_bitmap, clipRect);
                    if (bitmap != IntPtr.Zero)
                    {
                        IntPtr hdcsource = CreateCompatibleDC(m_hDC);
                        SelectObject(hdcsource, bitmap);
                        StretchBlt(m_hDC, clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height, hdcsource, 0, 0, clipRect.Width, clipRect.Height, 13369376);
                        DeleteObject(bitmap);
                        DeleteObject(hdcsource);
                    }
                }

            }
            else
            {
                if (clipRect.Width > 0 && clipRect.Height > 0)
                {
                    IntPtr bitmap = create_hbitmap_from_gdiplus_bitmap(m_bitmap, clipRect);
                    if (bitmap != IntPtr.Zero)
                    {
                        IntPtr hdcsource = CreateCompatibleDC(m_hDC);
                        SelectObject(hdcsource, bitmap);
                        StretchBlt(m_hDC, 0, 0, width, height, hdcsource, 0, 0, width, height, 13369376);
                        DeleteObject(bitmap);
                        DeleteObject(hdcsource);
                    }
                }
            }
            m_offsetX = 0;
            m_offsetY = 0;
            m_opacity = 1;
            m_resourcePath = "";
        }

        /// <summary>
        /// 反裁剪路径
        /// </summary>
        public override void excludeClipPath()
        {
            Region region = new Region(m_path);
            m_g.ExcludeClip(region);
            region.Dispose();
        }

        /// <summary>
        /// 设置裁剪区域
        /// </summary>
        /// <param name="rect">区域</param>
        public virtual void excludeClip(FCRect rect)
        {
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                gdiPlusRect.X = (int)Math.Floor(gdiPlusRect.X * m_scaleFactorX);
                gdiPlusRect.Y = (int)Math.Floor(gdiPlusRect.Y * m_scaleFactorY);
                gdiPlusRect.Width = (int)Math.Ceiling(gdiPlusRect.Width * m_scaleFactorX);
                gdiPlusRect.Height = (int)Math.Ceiling(gdiPlusRect.Height * m_scaleFactorY);
            }
            m_g.ExcludeClip(gdiPlusRect);
        }

        /// <summary>
        /// 填充椭圆
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        public override void fillEllipse(long dwPenColor, FCRect rect)
        {
            fillEllipse(dwPenColor, rect.left, rect.top, rect.right, rect.bottom);
        }

        /// <summary>
        /// 填充椭圆
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void fillEllipse(long dwPenColor, int left, int top, int right, int bottom)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = right - left;
            if (rw < 1) rw = 1;
            int rh = bottom - top;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(left + m_offsetX, top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                try
                {
                    m_g.FillEllipse(getBrush(dwPenColor), gdiPlusRect);
                }
                catch (Exception ex)
                {
                }
            }
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制渐变椭圆
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="rect">矩形</param>
        /// <param name="angle">角度</param>
        public override void fillGradientEllipse(long dwFirst, long dwSecond, FCRect rect, int angle)
        {
            int rw = rect.right - rect.left;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            LinearGradientBrush lgb = new LinearGradientBrush(gdiPlusRect, getGdiPlusColor(dwFirst), getGdiPlusColor(dwSecond), angle);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.FillEllipse(lgb, gdiPlusRect);
            }
            m_g.SmoothingMode = SmoothingMode.Default;
            lgb.Dispose();
        }

        /// <summary>
        /// 填充渐变路径
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="points">点的集合</param>
        /// <param name="angle">角度</param>
        public override void fillGradientPath(long dwFirst, long dwSecond, FCRect rect, int angle)
        {
            int rw = rect.right - rect.left;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            LinearGradientBrush lgb = new LinearGradientBrush(gdiPlusRect, getGdiPlusColor(dwFirst), getGdiPlusColor(dwSecond), angle);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.FillPath(lgb, m_path);
            m_g.SmoothingMode = SmoothingMode.Default;
            lgb.Dispose();
        }

        /// <summary>
        /// 绘制渐变的多边形
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="rect">点的集合</param>
        /// <param name="angle">角度</param>
        public override void fillGradientPolygon(long dwFirst, long dwSecond, FCPoint[] points, int angle)
        {
            int left = 0, top = 0, right = 0, bottom = 0;
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                if (i == 0)
                {
                    left = x;
                    top = y;
                    right = x;
                    bottom = y;
                }
                else
                {
                    if (x < left)
                    {
                        left = x;
                    }
                    if (y < top)
                    {
                        top = y;
                    }
                    if (x > right)
                    {
                        right = x;
                    }
                    if (y > bottom)
                    {
                        bottom = y;
                    }
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            Rectangle gdiPlusRect = new Rectangle(left, top, right - left, bottom - top);
            if (gdiPlusRect.Height > 0)
            {
                LinearGradientBrush lgb = new LinearGradientBrush(gdiPlusRect, getGdiPlusColor(dwFirst), getGdiPlusColor(dwSecond), angle);
                if (!m_noSmooth)
                {
                    m_g.SmoothingMode = SmoothingMode.AntiAlias;
                }
                m_g.FillPolygon(lgb, gdiPlusPoints);
                m_g.SmoothingMode = SmoothingMode.Default;
                lgb.Dispose();
            }
        }

        /// <summary>
        /// 绘制渐变矩形
        /// </summary>
        /// <param name="dwFirst">开始颜色</param>
        /// <param name="dwSecond">结束颜色</param>
        /// <param name="rect">矩形</param>
        /// <param name="cornerRadius">边角半径</param>
        /// <param name="angle">角度</param>
        public override void fillGradientRect(long dwFirst, long dwSecond, FCRect rect, int cornerRadius, int angle)
        {
            int rw = rect.right - rect.left;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            LinearGradientBrush lgb = new LinearGradientBrush(gdiPlusRect, getGdiPlusColor(dwFirst), getGdiPlusColor(dwSecond), angle);
            if (cornerRadius != 0)
            {
                GraphicsPath gdiPlusPath = getRoundRectPath(gdiPlusRect, (int)(cornerRadius * Math.Min(m_scaleFactorX, m_scaleFactorY)));
                if (!m_noSmooth)
                {
                    m_g.SmoothingMode = SmoothingMode.AntiAlias;
                }
                m_g.FillPath(lgb, gdiPlusPath);
                m_g.SmoothingMode = SmoothingMode.Default;
                gdiPlusPath.Dispose();
            }
            else
            {
                if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
                {
                    m_g.SmoothingMode = SmoothingMode.Default;
                    m_g.FillRectangle(lgb, gdiPlusRect);
                }
            }
            lgb.Dispose();
        }

        /// <summary>
        /// 填充路径
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        public override void fillPath(long dwPenColor)
        {
            if (dwPenColor == FCColor.None) return;
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.FillPath(getBrush(dwPenColor), m_path);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制扇形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="startAngle">从 x 轴到弧线的起始点沿顺时针方向度量的角（以度为单位）</param>
        /// <param name="sweepAngle">从 startAngle 参数到弧线的结束点沿顺时针方向度量的角（以度为单位）</param>
        public override void fillPie(long dwPenColor, FCRect rect, float startAngle, float sweepAngle)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left - 1;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top - 1;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.FillPie(getBrush(dwPenColor), gdiPlusRect, startAngle, sweepAngle);
            }
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 填充多边形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="points">点的数组</param>
        public override void fillPolygon(long dwPenColor, FCPoint[] points)
        {
            if (dwPenColor == FCColor.None) return;
            Point[] gdiPlusPoints = new Point[points.Length];
            for (int i = 0; i < gdiPlusPoints.Length; i++)
            {
                int x = points[i].x + m_offsetX;
                int y = points[i].y + m_offsetY;
                if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
                {
                    x = (int)(m_scaleFactorX * x);
                    y = (int)(m_scaleFactorY * y);
                }
                Point p = new Point(x, y);
                gdiPlusPoints[i] = p;
            }
            if (!m_noSmooth)
            {
                m_g.SmoothingMode = SmoothingMode.AntiAlias;
            }
            m_g.FillPolygon(getBrush(dwPenColor), gdiPlusPoints);
            m_g.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 填充矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        public override void fillRect(long dwPenColor, FCRect rect)
        {
            fillRect(dwPenColor, rect.left, rect.top, rect.right, rect.bottom);
        }

        /// <summary>
        /// 填充矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="left">左侧坐标</param>
        /// <param name="top">顶部左标</param>
        /// <param name="right">右侧坐标</param>
        /// <param name="bottom">底部坐标</param>
        public override void fillRect(long dwPenColor, int left, int top, int right, int bottom)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = right - left;
            if (rw < 1) rw = 1;
            int rh = bottom - top;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(left + m_offsetX, top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
            {
                m_g.SmoothingMode = SmoothingMode.Default;
                m_g.FillRectangle(getBrush(dwPenColor), gdiPlusRect);
            }
        }

        /// <summary>
        /// 填充圆角矩形
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="rect">矩形区域</param>
        /// <param name="cornerRadius">边角半径</param>
        public override void fillRoundRect(long dwPenColor, FCRect rect, int cornerRadius)
        {
            if (dwPenColor == FCColor.None) return;
            int rw = rect.right - rect.left;
            if (rw < 1) rw = 1;
            int rh = rect.bottom - rect.top;
            if (rh < 1) rh = 1;
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rw, rh);
            affectScaleFactor(ref gdiPlusRect);
            if (cornerRadius != 0)
            {
                GraphicsPath gdiPlusPath = getRoundRectPath(gdiPlusRect, (int)(cornerRadius * Math.Min(m_scaleFactorX, m_scaleFactorY)));
                if (!m_noSmooth)
                {
                    m_g.SmoothingMode = SmoothingMode.AntiAlias;
                }
                m_g.FillPath(getBrush(dwPenColor), gdiPlusPath);
                m_g.SmoothingMode = SmoothingMode.Default;
                gdiPlusPath.Dispose();
            }
            else
            {
                if (gdiPlusRect.Width > 0 && gdiPlusRect.Height > 0)
                {
                    m_g.SmoothingMode = SmoothingMode.Default;
                    m_g.FillRectangle(getBrush(dwPenColor), gdiPlusRect);
                }
            }
        }

        /// <summary>
        /// 获取画刷
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <returns>画刷</returns>
        public SolidBrush getBrush(long dwPenColor)
        {
            Color gdiColor = getGdiPlusColor(dwPenColor);
            if (m_brush == null)
            {
                m_brush = new SolidBrush(gdiColor);
                if (m_opacity == 1)
                {
                    m_brushColor = dwPenColor;
                }
                else
                {
                    m_brushColor = FCColor.None;
                }
            }
            else
            {
                if (m_brushColor == FCColor.None || m_brushColor != dwPenColor)
                {
                    m_brush.Color = gdiColor;
                    m_brushColor = dwPenColor;
                }
                if (m_opacity != 1)
                {
                    m_brushColor = FCColor.None;
                }
            }
            return m_brush;
        }

        /// <summary>
        /// 获取颜色
        /// </summary>
        /// <param name="dwPenColor">输入颜色</param>
        /// <returns>输出颜色</returns>
        public override long getColor(long dwPenColor)
        {
            long color = dwPenColor;
            if (dwPenColor < FCColor.None)
            {
                color = m_myColor.getUserColor(dwPenColor);
            }
            return color;
        }

        /// <summary>
        /// 获取要绘制的颜色
        /// </summary>
        /// <param name="dwPenColor">输入颜色</param>
        /// <returns>输出颜色</returns>
        public override long getPaintColor(long dwPenColor)
        {
            dwPenColor = getColor(dwPenColor);
            return dwPenColor;
        }

        /// <summary>
        /// 是否允许反色
        /// </summary>
        public bool m_allowReverseColor = true;

        /// <summary>
        /// 获取颜色
        /// </summary>
        /// <param name="dwPenColor">整型颜色</param>
        /// <returns>Gdi颜色</returns>
        public Color getGdiPlusColor(long dwPenColor)
        {
            long c = dwPenColor;
            if (dwPenColor < FCColor.None)
            {
                dwPenColor = m_myColor.getUserColor(dwPenColor);
            }
            int a = 255;
            if (dwPenColor < 0)
            {
                dwPenColor = Math.Abs(dwPenColor);
                a = (int)(dwPenColor - dwPenColor / 1000 * 1000);
                dwPenColor /= 1000;
            }
            if (m_opacity < 1)
            {
                a = (int)(a * m_opacity);
            }
            int r = (int)(dwPenColor & 0xff);
            int g = (int)((dwPenColor >> 8) & 0xff);
            int b = (int)((dwPenColor >> 0x10) & 0xff);
            return Color.FromArgb(a, r, g, b);
        }

        public static HashMap<String, Font> m_fonts = new HashMap<String, Font>();

        /// <summary>
        /// 获取Gdi字体
        /// </summary>
        /// <param name="font">字体</param>
        /// <returns>Gdi字体</returns>
        public Font getFont(FCFont font)
        {
            if (font.m_fontSize < 1)
            {
                font.m_fontSize = 1;
            }
            float fontSize = font.m_fontSize;
            String fontFamily = font.m_fontFamily;
            String key = null;
            if (fontFamily == "Default")
            {
                fontFamily = MyColor.getSystemFont();
            }
            key = String.Format("{0} {1} {2}{3}{4}{5}", fontFamily, font.m_fontSize, font.m_bold ? "1" : "0", font.m_italic ? "1" : "0", font.m_strikeout ? "1" : "0", font.m_underline ? "1" : "0");
            Font rFont = null;
            if (m_fonts.TryGetValue(key, out rFont))
            {
            }
            else
            {
                if (font.m_strikeout)
                {
                    if (font.m_bold && font.m_underline && font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Underline | FontStyle.Italic | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else if (font.m_bold && font.m_underline)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Underline | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else if (font.m_bold && font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Italic | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else if (font.m_underline && font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Underline | FontStyle.Italic | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else if (font.m_bold)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else if (font.m_underline)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Underline | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else if (font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Italic | FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                    else
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Strikeout, GraphicsUnit.Pixel);
                    }
                }
                else
                {
                    if (font.m_bold && font.m_underline && font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Underline | FontStyle.Italic, GraphicsUnit.Pixel);
                    }
                    else if (font.m_bold && font.m_underline)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Underline, GraphicsUnit.Pixel);
                    }
                    else if (font.m_bold && font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Pixel);
                    }
                    else if (font.m_underline && font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Underline | FontStyle.Italic, GraphicsUnit.Pixel);
                    }
                    else if (font.m_bold)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
                    }
                    else if (font.m_underline)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Underline, GraphicsUnit.Pixel);
                    }
                    else if (font.m_italic)
                    {
                        rFont = new Font(fontFamily, fontSize, FontStyle.Italic, GraphicsUnit.Pixel);
                    }
                    else
                    {
                        rFont = new Font(fontFamily, fontSize, GraphicsUnit.Pixel);
                    }
                }
                m_fonts.put(key, rFont);
            }
            return rFont;
        }

        /// <summary>
        /// 获取偏移
        /// </summary>
        /// <returns>偏移坐标</returns>
        public override FCPoint getOffset()
        {
            return new FCPoint(m_offsetX, m_offsetY);
        }

        /// <summary>
        /// 获取缩放比例
        /// </summary>
        /// <param name="scaleFactorX">横向缩放比例</param>
        /// <param name="scaleFactorY">纵向缩放比例</param>
        public override void getScaleFactor(ref double scaleFactorX, ref double scaleFactorY)
        {
            scaleFactorX = m_scaleFactorX;
            scaleFactorY = m_scaleFactorY;
        }

        public float[] m_dashPattern = null;

        public float m_dashOffset;

        public String m_lineCap = "";

        public String m_lineJoin = "";

        /// <summary>
        /// 获取画笔
        /// </summary>
        /// <param name="dwPenColor">颜色</param>
        /// <param name="width">宽度</param>
        /// <param name="style">样式</param>
        /// <returns>画笔</returns>
        public Pen getPen(long dwPenColor, float width, int style)
        {
            Color gdiColor = getGdiPlusColor(dwPenColor);
            if (m_pen == null)
            {
                float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
                if (lineWidth < 1)
                {
                    lineWidth = 1;
                }
                m_pen = new Pen(gdiColor, lineWidth);
                if (style == 0)
                {
                    m_pen.DashStyle = DashStyle.Solid;
                }
                else if (style == 1)
                {
                    m_pen.DashStyle = DashStyle.Dash;
                }
                else if (style == 2)
                {
                    m_pen.DashStyle = DashStyle.Dot;
                }
                if (m_opacity == 1)
                {
                    m_penColor = dwPenColor;
                }
                else
                {
                    m_penColor = FCColor.None;
                }
                m_penWidth = lineWidth;
                m_penStyle = style;
                switch (m_startLineCap)
                {
                    case 0:
                        m_pen.StartCap = LineCap.Flat;
                        break;
                    case 1:
                        m_pen.StartCap = LineCap.Square;
                        break;
                    case 2:
                        m_pen.StartCap = LineCap.Round;
                        break;
                    case 3:
                        m_pen.StartCap = LineCap.Triangle;
                        break;
                    case 4:
                        m_pen.StartCap = LineCap.NoAnchor;
                        break;
                    case 5:
                        m_pen.StartCap = LineCap.SquareAnchor;
                        break;
                    case 6:
                        m_pen.StartCap = LineCap.RoundAnchor;
                        break;
                    case 7:
                        m_pen.StartCap = LineCap.DiamondAnchor;
                        break;
                    case 8:
                        m_pen.StartCap = LineCap.ArrowAnchor;
                        break;
                    case 9:
                        m_pen.StartCap = LineCap.AnchorMask;
                        break;
                    case 10:
                        m_pen.StartCap = LineCap.Custom;
                        break;
                }
                switch (m_endLineCap)
                {
                    case 0:
                        m_pen.EndCap = LineCap.Flat;
                        break;
                    case 1:
                        m_pen.EndCap = LineCap.Square;
                        break;
                    case 2:
                        m_pen.EndCap = LineCap.Round;
                        break;
                    case 3:
                        m_pen.EndCap = LineCap.Triangle;
                        break;
                    case 4:
                        m_pen.EndCap = LineCap.NoAnchor;
                        break;
                    case 5:
                        m_pen.EndCap = LineCap.SquareAnchor;
                        break;
                    case 6:
                        m_pen.EndCap = LineCap.RoundAnchor;
                        break;
                    case 7:
                        m_pen.EndCap = LineCap.DiamondAnchor;
                        break;
                    case 8:
                        m_pen.EndCap = LineCap.ArrowAnchor;
                        break;
                    case 9:
                        m_pen.EndCap = LineCap.AnchorMask;
                        break;
                    case 10:
                        m_pen.EndCap = LineCap.Custom;
                        break;
                }
            }
            else
            {
                float lineWidth = (float)(width * Math.Min(m_scaleFactorX, m_scaleFactorY));
                if (lineWidth < 1)
                {
                    lineWidth = 1;
                }
                if (m_penColor == FCColor.None || m_penColor != dwPenColor)
                {
                    m_pen.Color = gdiColor;
                    m_penColor = dwPenColor;
                }
                if (m_opacity != 1)
                {
                    m_penColor = FCColor.None;
                }
                if (m_penWidth != lineWidth)
                {
                    m_pen.Width = lineWidth;
                    m_penWidth = lineWidth;
                }
                if (m_penStyle != style)
                {
                    if (style == 0)
                    {
                        m_pen.DashStyle = DashStyle.Solid;
                    }
                    else if (style == 1)
                    {
                        m_pen.DashStyle = DashStyle.Dash;
                    }
                    else if (style == 2)
                    {
                        m_pen.DashStyle = DashStyle.Dot;
                    }
                    m_penStyle = style;
                }
            }
            if (m_dashPattern != null)
            {
                m_pen.DashStyle = DashStyle.Custom;
                m_pen.DashPattern = m_dashPattern;
            }
            if (m_dashOffset != 0)
            {
                m_pen.DashStyle = DashStyle.Custom;
                m_pen.DashOffset = m_dashOffset;
            }
            if (m_lineCap.Length > 0)
            {
                if (m_lineCap == "butt")
                {
                    m_pen.StartCap = LineCap.Flat;
                    m_pen.EndCap = LineCap.Flat;
                }
                else if (m_lineCap == "round")
                {
                    m_pen.StartCap = LineCap.Round;
                    m_pen.EndCap = LineCap.Round;
                }
                else if (m_lineCap == "square")
                {
                    m_pen.StartCap = LineCap.Square;
                    m_pen.EndCap = LineCap.Square;
                }
            }
            if (m_lineJoin.Length > 0)
            {
                if (m_lineJoin == "miter")
                {
                    m_pen.LineJoin = LineJoin.Miter;
                }
                else if (m_lineJoin == "bevel")
                {
                    m_pen.LineJoin = LineJoin.Bevel;
                }
                else if (m_lineJoin == "round")
                {
                    m_pen.LineJoin = LineJoin.Round;
                }
            }
            return m_pen;
        }

        /// <summary>
        /// 获取绘制圆形矩形的路径
        /// </summary>
        /// <param name="gdiPlusRect">矩形</param>
        /// <param name="cornerRadius">边角半径</param>
        /// <returns>路径</returns>
        public static GraphicsPath getRoundRectPath(Rectangle gdiPlusRect, int cornerRadius)
        {
            if (gdiPlusRect.Width > 1)
            {
                gdiPlusRect.Width -= 1;
            }
            int width = gdiPlusRect.Width, height = gdiPlusRect.Height;
            try
            {
                GraphicsPath gdiPlusPath = new GraphicsPath();
                gdiPlusPath.AddArc(gdiPlusRect.X, gdiPlusRect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
                gdiPlusPath.AddLine(gdiPlusRect.X + cornerRadius, gdiPlusRect.Y, gdiPlusRect.Right - cornerRadius * 2, gdiPlusRect.Y);
                gdiPlusPath.AddArc(gdiPlusRect.X + gdiPlusRect.Width - cornerRadius * 2, gdiPlusRect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
                gdiPlusPath.AddLine(gdiPlusRect.Right, gdiPlusRect.Y + cornerRadius * 2, gdiPlusRect.Right, gdiPlusRect.Y + gdiPlusRect.Height - cornerRadius * 2);
                gdiPlusPath.AddArc(gdiPlusRect.X + gdiPlusRect.Width - cornerRadius * 2, gdiPlusRect.Y + gdiPlusRect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
                gdiPlusPath.AddLine(gdiPlusRect.Right - cornerRadius * 2, gdiPlusRect.Bottom, gdiPlusRect.X + cornerRadius * 2, gdiPlusRect.Bottom);
                gdiPlusPath.AddArc(gdiPlusRect.X, gdiPlusRect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
                gdiPlusPath.AddLine(gdiPlusRect.X, gdiPlusRect.Bottom - cornerRadius * 2, gdiPlusRect.X, gdiPlusRect.Y + cornerRadius * 2);
                gdiPlusPath.CloseFigure();
                return gdiPlusPath;
            }
            catch (Exception ex)
            {
                GraphicsPath gdiPlusPath = new GraphicsPath();
                gdiPlusPath.AddRectangle(gdiPlusRect);
                return gdiPlusPath;
            }
        }

        /// <summary>
        /// 旋转角度
        /// </summary>
        /// <param name="op">圆心坐标</param>
        /// <param name="mp">点的坐标</param>
        /// <param name="angle">角度</param>
        /// <returns>结果坐标</returns>
        public override FCPoint rotate(FCPoint op, FCPoint mp, int angle)
        {
            float PI = 3.14159265f;
            FCPoint pt = new FCPoint();
            pt.x = (int)((mp.x - op.x) * Math.Cos(angle * PI / 180) - (mp.y - op.y) * Math.Sin(angle * PI / 180) + op.x);
            pt.y = (int)((mp.x - op.x) * Math.Sin(angle * PI / 180) + (mp.y - op.y) * Math.Cos(angle * PI / 180) + op.y);
            return pt;
        }

        /// <summary>
        /// 设置裁剪区域
        /// </summary>
        /// <param name="rect">区域</param>
        public override void setClip(FCRect rect)
        {
            Rectangle gdiPlusRect = new Rectangle(rect.left + m_offsetX, rect.top + m_offsetY, rect.right - rect.left, rect.bottom - rect.top);
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                gdiPlusRect.X = (int)Math.Floor(gdiPlusRect.X * m_scaleFactorX);
                gdiPlusRect.Y = (int)Math.Floor(gdiPlusRect.Y * m_scaleFactorY);
                gdiPlusRect.Width = (int)Math.Ceiling(gdiPlusRect.Width * m_scaleFactorX);
                gdiPlusRect.Height = (int)Math.Ceiling(gdiPlusRect.Height * m_scaleFactorY);
            }
            m_g.SetClip(gdiPlusRect);
        }

        /// <summary>
        /// 设置直线两端的样式
        /// </summary>
        /// <param name="startLineCap">开始的样式</param>
        /// <param name="endLineCap">结束的样式</param>
        public override void setLineCap(int startLineCap, int endLineCap)
        {
            m_startLineCap = startLineCap;
            m_endLineCap = endLineCap;
            if (m_pen != null)
            {
                switch (m_startLineCap)
                {
                    case 0:
                        m_pen.StartCap = LineCap.Flat;
                        break;
                    case 1:
                        m_pen.StartCap = LineCap.Square;
                        break;
                    case 2:
                        m_pen.StartCap = LineCap.Round;
                        break;
                    case 3:
                        m_pen.StartCap = LineCap.Triangle;
                        break;
                    case 4:
                        m_pen.StartCap = LineCap.NoAnchor;
                        break;
                    case 5:
                        m_pen.StartCap = LineCap.SquareAnchor;
                        break;
                    case 6:
                        m_pen.StartCap = LineCap.RoundAnchor;
                        break;
                    case 7:
                        m_pen.StartCap = LineCap.DiamondAnchor;
                        break;
                    case 8:
                        m_pen.StartCap = LineCap.ArrowAnchor;
                        break;
                    case 9:
                        m_pen.StartCap = LineCap.AnchorMask;
                        break;
                    case 10:
                        m_pen.StartCap = LineCap.Custom;
                        break;
                }
                switch (m_endLineCap)
                {
                    case 0:
                        m_pen.EndCap = LineCap.Flat;
                        break;
                    case 1:
                        m_pen.EndCap = LineCap.Square;
                        break;
                    case 2:
                        m_pen.EndCap = LineCap.Round;
                        break;
                    case 3:
                        m_pen.EndCap = LineCap.Triangle;
                        break;
                    case 4:
                        m_pen.EndCap = LineCap.NoAnchor;
                        break;
                    case 5:
                        m_pen.EndCap = LineCap.SquareAnchor;
                        break;
                    case 6:
                        m_pen.EndCap = LineCap.RoundAnchor;
                        break;
                    case 7:
                        m_pen.EndCap = LineCap.DiamondAnchor;
                        break;
                    case 8:
                        m_pen.EndCap = LineCap.ArrowAnchor;
                        break;
                    case 9:
                        m_pen.EndCap = LineCap.AnchorMask;
                        break;
                    case 10:
                        m_pen.EndCap = LineCap.Custom;
                        break;
                }
            }
        }

        /// <summary>
        /// 设置偏移
        /// </summary>
        /// <param name="mp">偏移坐标</param>
        public override void setOffset(FCPoint mp)
        {
            m_offsetX = mp.x;
            m_offsetY = mp.y;
        }

        /// <summary>
        /// 设置透明度
        /// </summary>
        /// <param name="opacity">透明度</param>
        public override void setOpacity(float opacity)
        {
            if (m_opacity != opacity)
            {
                m_opacity = opacity;
                if (m_brush != null)
                {
                    m_brush.Dispose();
                    m_brush = null;
                }
                if (m_pen != null)
                {
                    m_pen.Dispose();
                    m_pen = null;
                }
            }
        }

        /// <summary>
        /// 设置缩放因子
        /// </summary>
        /// <param name="scaleFactorX">横向因子</param>
        /// <param name="scaleFactorY">纵向因子</param>
        public override void setScaleFactor(double scaleFactorX, double scaleFactorY)
        {
            m_scaleFactorX = scaleFactorX;
            m_scaleFactorY = scaleFactorY;
        }

        /// <summary>
        /// 设置资源的路径
        /// </summary>
        /// <param name="resourcePath">资源的路径</param>
        public override void setResourcePath(String resourcePath)
        {
            m_resourcePath = resourcePath;
        }

        /// <summary>
        /// 设置旋转角度
        /// </summary>
        /// <param name="rotateAngle">旋转角度</param>
        public override void setRotateAngle(int rotateAngle)
        {
            m_rotateAngle = rotateAngle;
        }

        /// <summary>
        /// 设置是否支持透明色
        /// </summary>
        /// <returns>是否支持</returns>
        public override bool supportTransparent()
        {
            return true;
        }

        /// <summary>
        /// 获取文字大小
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="font">字体</param>z
        /// <returns>字体大小</returns>
        public override FCSize textSize(String text, FCFont font, int width)
        {
            if (m_emptyStringFormat == null)
            {
                m_emptyStringFormat = StringFormat.GenericTypographic;
                ////m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            int gWidth = Int32.MaxValue;
            if (text == " ")
            {
                m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                float rate = (float)((m_scaleFactorX + m_scaleFactorY) / 2);
                if (width != -1)
                {
                    gWidth = (int)(width * rate);
                }
                float fontSize = (float)(font.m_fontSize * rate);
                FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                Size gdiPlusSize = m_g.MeasureString(text, getFont(scaleFont), gWidth, m_emptyStringFormat).ToSize();
                if (text == " ")
                {
                    m_emptyStringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                }
                return new FCSize((int)(gdiPlusSize.Width / rate), (int)(gdiPlusSize.Height / rate));
            }
            else
            {
                if (width != -1)
                {
                    gWidth = width;
                }
                Size gdiPlusSize = m_g.MeasureString(text, getFont(font), gWidth, m_emptyStringFormat).ToSize();
                if (text == " ")
                {
                    m_emptyStringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                }
                return new FCSize(gdiPlusSize.Width, gdiPlusSize.Height);
            }
        }

        /// <summary>
        /// 获取文字大小
        /// </summary>
        /// <param name="text">文字</param>
        /// <param name="font">字体</param>
        /// <returns>字体大小</returns>
        public override FCSizeF textSizeF(String text, FCFont font, int width)
        {
            if (m_emptyStringFormat == null)
            {
                m_emptyStringFormat = StringFormat.GenericTypographic;
                ////m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            int gWidth = Int32.MaxValue;
            if (text == " ")
            {
                m_emptyStringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
            }
            if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
            {
                float rate = (float)((m_scaleFactorX + m_scaleFactorY) / 2);
                if (width != -1)
                {
                    gWidth = (int)(width * rate);
                }
                float fontSize = (float)(font.m_fontSize * rate);
                FCFont scaleFont = new FCFont(font.m_fontFamily, fontSize, font.m_bold, font.m_underline, font.m_italic);
                Size gdiPlusSize = m_g.MeasureString(text, getFont(scaleFont), gWidth, m_emptyStringFormat).ToSize();
                if (text == " ")
                {
                    m_emptyStringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                }
                return new FCSizeF(gdiPlusSize.Width / rate, gdiPlusSize.Height / rate);
            }
            else
            {
                if (width != -1)
                {
                    gWidth = width;
                }
                SizeF gdiPlusSize = m_g.MeasureString(text, getFont(font), gWidth, m_emptyStringFormat);
                if (text == " ")
                {
                    m_emptyStringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
                }
                return new FCSizeF(gdiPlusSize.Width, gdiPlusSize.Height);
            }
        }
    }
}